package logica.persistencia;


import java.util.List;
import logica.Atributo;
import logica.AtributoIdentificadorFaltanteException;
import logica.AtributoRepetidoException;
import logica.Entidad;
import logica.EntidadIdentificadoraFaltanteException;
import logica.IdExternoRepetidoException;
import logica.Identificador;
import logica.IdentificadorVacioException;
import logica.TipoDeEntidad;


import org.jdom.Element;

import vista.objetos.EntidadGraficable;
import xml.ConstantesXml;
import xml.XMLManager;

public class EntidadPersistente extends ObjetoDiagramaPersistente{
		
	public EntidadPersistente(Entidad entidad) {
		super(entidad);
		
	}
				
	public EntidadPersistente(EntidadGraficable entidadGraficable) {
		super(entidadGraficable);
	}

	@Override
	public void serializar() {
		Element elementoEntidad = new Element (ConstantesXml.ELEMENTO_ENTIDAD);
		Entidad entidad  = (Entidad) this.getObjetoDiagrama();
		
		super.serializarElementoGenerico(elementoEntidad);
		elementoEntidad.setAttribute(ConstantesXml.ATRIBUTO_NOMBRE, entidad.getNombre());
		elementoEntidad.setAttribute(ConstantesXml.ATRIBUTO_TIPO, entidad.getTipo().toString());
		
		if (entidad.getAtributos().size() > 0) {
			Element listaAtributos = new Element (ConstantesXml.LISTA_ATRIBUTOS);	
			for (Atributo atributo : entidad.getAtributos()) {
				AtributoPersistente atribP = atributo.getAtributoPersistente();
				atribP.setPadre(listaAtributos);
				atribP.serializar();
			}
			elementoEntidad.addContent(listaAtributos);
				
		}
		
		if (entidad.getIdentificadores().size() > 0) {
			Element listaIdentificadores = new Element (ConstantesXml.LISTA_IDENTIFICADORES);	
			
			for (Identificador ident : entidad.getIdentificadores()) {
				IdentificadorPersistente identP = ident.getIdentificadorPersistente();
				Element elemIden = new Element (ConstantesXml.ELEMENTO_IDENTIFICADOR);
				identP.setPadre(elemIden);
				identP.serializar();
				XMLManager.getInstance().agregarElementoAElemento(listaIdentificadores, elemIden);
				
			}
			elementoEntidad.addContent(listaIdentificadores);
				
		}
		
		if (entidad.getReferenciaAEntidadesExternas().size() > 0) {
			Element idExtenernos = new Element (ConstantesXml.LISTA_IDENTIFICADORES_EXTERNOS);	
			
			for (Entidad ent : entidad.getReferenciaAEntidadesExternas()) {
				EntidadPersistente entP = ent.getObjetoDiagramaPersistente();
				Element elemIdenExt = new Element (ConstantesXml.ELEMENTO_IDENTIFICADOR_EXTERNO);
				int idRef = entP.getIdentificador();
				String nombreRef = ent.getNombre();
				elemIdenExt.setAttribute(ConstantesXml.ATRIBUTO_ID_REF, String.valueOf(idRef));
				elemIdenExt.setAttribute(ConstantesXml.ATRIBUTO_NOMBRE_REF, nombreRef);
				XMLManager.getInstance().agregarElementoAElemento(idExtenernos, elemIdenExt);
				
				
			}
			elementoEntidad.addContent(idExtenernos);
		
		}
		
		XMLManager.getInstance().agregarElementoAObjetos(elementoEntidad);
	}


	public void hidratar(Element elementoEntidad) {
		String tipo = elementoEntidad.getAttributeValue(ConstantesXml.ATRIBUTO_TIPO);
		Entidad entidad = (Entidad)this.getObjetoDiagrama();
		
		//Hasheo el elemento para poder obtenerlo después a través del id
		String claveHash = elementoEntidad.getAttributeValue(ConstantesXml.ATRIBUTO_ID_OBJETO);
		XMLManager.getInstance().hashObjetoDiagramaConClave(claveHash, this.getObjetoDiagrama());
		
		entidad.setTipo(TipoDeEntidad.valueOf(tipo));
		
		
		Element elementoAtributos = elementoEntidad.getChild(ConstantesXml.LISTA_ATRIBUTOS);
		
		if (elementoAtributos != null) {
			@SuppressWarnings("unchecked")
			List <Element> elementListaAtributosSimples = elementoAtributos.getChildren(ConstantesXml.ELEMENTO_ATRIBUTO_SIMPLE);
			List <Atributo> listaAtribSimples = AtributoSimplePersistente.hidratarListaAtributosSimples(elementListaAtributosSimples);
			try {
				entidad.agregarAtributos(listaAtribSimples);
			} catch (AtributoRepetidoException e) {
				e.printStackTrace();
			}
			@SuppressWarnings("unchecked")
			List <Element> elementListaAtributosCompuestos = elementoAtributos.getChildren(ConstantesXml.ELEMENTO_ATRIBUTO_COMPUESTO);
			List <Atributo> listaAtribCompuestos = AtributoCompuestoPersistente.hidratarListaAtributosCompuestos(elementListaAtributosCompuestos);
			try {
				entidad.agregarAtributos(listaAtribCompuestos);
			} catch (AtributoRepetidoException e) {
				e.printStackTrace();
			}
		}
	

	}
	
	public void hidratarIdentificadores(Element elementoEntidad) {
		Entidad entidad = (Entidad)this.getObjetoDiagrama();
		Element elementoIdentificadoresExternos = elementoEntidad.getChild(ConstantesXml.LISTA_IDENTIFICADORES_EXTERNOS);
		if (elementoIdentificadoresExternos != null ) {
			@SuppressWarnings("unchecked")
			List <Element> elementListaIdentificadoresExternos = elementoIdentificadoresExternos.getChildren(ConstantesXml.ELEMENTO_IDENTIFICADOR_EXTERNO);
			for (Element elementoIdentificadorExterno : elementListaIdentificadoresExternos) {
				String claveHashEnt = elementoIdentificadorExterno.getAttributeValue(ConstantesXml.ATRIBUTO_ID_REF);
				String nombreEnt = elementoIdentificadorExterno.getAttributeValue(ConstantesXml.ATRIBUTO_NOMBRE_REF);
				Entidad ent = (Entidad) XMLManager.getInstance().objtenerObjetoDiagramaConClave(claveHashEnt);
				if (ent != null && ent.getNombre().equals(nombreEnt)) {
					try {
						entidad.agregarEntidadExterna(ent);
					} catch (IdExternoRepetidoException e) {
						//e.printStackTrace(); esta exception salta porq se está hidratando tantas veces como
						//copia de la entidad, no importa q suceda ya q siempre se está agregando la misma refe
					
					}
				}	
				
			}
		}
		
		
		Element elementoIdentificadores = elementoEntidad.getChild(ConstantesXml.LISTA_IDENTIFICADORES);
		
		if (elementoIdentificadores != null) {
			@SuppressWarnings("unchecked")
			List <Element> elementListaIdentificadores = elementoIdentificadores.getChildren();
			for (Element elementoIdentificador : elementListaIdentificadores) {
				Identificador identificador;
				try {
					identificador = new Identificador();
					IdentificadorPersistente identP = new IdentificadorPersistente(identificador);
					identP.hidratar(elementoIdentificador);
					entidad.agregarIdentificador(identificador);
				} catch (AtributoIdentificadorFaltanteException e) {
					e.printStackTrace();
				} catch (EntidadIdentificadoraFaltanteException e) {
					e.printStackTrace();
				} catch (IdentificadorVacioException e) {
					e.printStackTrace();
				}
			}
		}
	}
	public static Entidad hidratarEntidadEnHash(Element elemento) {
		String claveHashEnt = elemento.getAttributeValue(ConstantesXml.ATRIBUTO_ID_REF);
		String nombreEnt = elemento.getAttributeValue(ConstantesXml.ATRIBUTO_NOMBRE_REF);
		Entidad ent = (Entidad) XMLManager.getInstance().objtenerObjetoDiagramaConClave(claveHashEnt);
		if (ent != null && ent.getNombre().equals(nombreEnt)) {
			return ent;
		}
		return null;
	}
}

